/*
 * Copyright (C),2015,北京新诺创科软件技术有限公司
 * author zhangmengliang
 */
package com.xnck.example.jertest.dao.helper;

import org.nutz.dao.Cnd;
import org.nutz.dao.Condition;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Entity;
import org.nutz.dao.pager.Pager;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.sql.SqlCallback;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.ParameterizedType;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * 数据处理基类
 * @author zhangmengliang
 *
 * @param <T>
 */
public class BaseDao<T> {
    protected Class<T> persistentClass;

    @Autowired
    protected Dao dao;
    public Dao getDao() {
        return dao;
    }
    public void setDao(Dao dao) {
        this.dao = dao;
    }
    public BaseDao()
    {
        // 获取持久化对象的类型  
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];
    }

    /**
     * 按主键查询
     * @param id String主键
     * @return
     * @throws
     * @author:zhangmengliang
     * @date: 2015年8月9日
     */
    public T get(String id){
        return dao.fetch(this.persistentClass, id);
    }

    /**
     * 按主键查询
     * @param id Int主键
     * @return
     * @throws
     * @author:zhangmengliang
     * @date: 2015年8月9日
     */
    public T get(Integer id){
        return dao.fetch(this.persistentClass, id);
    }
    /**
     * 符合主键查询
     * @param objects 参数,@PK里声明的顺序
     * @return
     */
    public T fetchx(Object... objects){
        return dao.fetchx(this.persistentClass, objects);
    }
    /**
     * 查询所有
     * @return
     * @throws
     * @author:zhangmengliang
     * @date: 2015年8月9日
     */
    public List<T> search(){
        return dao.query(this.persistentClass, null);
    }

    /**
     * 分页查询所有
     * @param currentPage 当前页
     * @param pageSize 每页数量
     * @return
     * @throws
     * @author:zhangmengliang
     * @date: 2015年8月9日
     */
    public List<T> search(int currentPage,int pageSize){
        Pager pager = dao.createPager(currentPage, pageSize);
        return dao.query(this.persistentClass, null, pager);
    }

    /**
     * 查询所有
     * @param orderBy 排序字段名称(asc)
     * @return
     * @throws
     * @author:zhangmengliang
     * @date: 2015年8月9日
     */
    public List<T> search(String orderBy){
        return dao.query(this.persistentClass, Cnd.orderBy().asc(orderBy), null);
    }

    /**
     * 分页查询所有
     * @param orderBy 排序字段名称(asc)
     * @param currentPage
     * @param pageSize
     * @return
     * @throws
     * @author:zhangmengliang
     * @date: 2015年8月9日
     */
    public List<T> search(String orderBy, int currentPage,int pageSize){
        Pager pager = dao.createPager(currentPage, pageSize);
        return dao.query(this.persistentClass, Cnd.orderBy().asc(orderBy), pager);
    }

    /**
     * 按条件查询
     * @param condition 输入的条件
     * @return
     * @throws
     * @author:zhangmengliang
     * @date: 2015年8月9日
     */
    public List<T> search(Condition condition){
        return dao.query(this.persistentClass, condition, null);
    }

    /**
     * 按条件分页查询
     * @param condition 条件
     * @param currentPage 当前页
     * @param pageSize 每页数量
     * @return
     * @throws
     * @author:zhangmengliang
     * @date: 2015年8月9日
     */
    public List<T> searchByPage(Condition condition, int currentPage, int pageSize){
        Pager pager = dao.createPager(currentPage, pageSize);
        return dao.query(this.persistentClass, condition, pager);
    }

    /**
     * 获取所有数据总数
     * @return
     * @throws
     * @author:zhangmengliang
     * @date: 2015年8月9日
     */
    public int searchCount(){
        return dao.count(this.persistentClass);
    }

    /**
     * 按条件获取所有数据总数
     * @param condition 条件
     * @return
     * @throws
     * @author:zhangmengliang
     * @date: 2015年8月9日
     */
    public int searchCount(Condition condition){
        return dao.count(this.persistentClass, condition);
    }

    /**
     * 按条件查询总数
     * @param sqlName sql名称
     * @param condition 条件
     * @return
     * @author:zhangmengliang
     * @date: 2015年10月14日
     */
    public int searchCount(String sqlName, Condition condition){
        Sql sql = dao.sqls().create(sqlName);
        sql.setCondition(condition);
        return this.searchCount(sql);
    }

    /**
     * 按条件查询总数
     * @param sql sql对象
     * @return
     * @author:zhangmengliang
     * @date: 2015年10月15日
     */
    public int searchCount(Sql sql){
        sql.setCallback(new SqlCallback() {
            public Object invoke(Connection conn, ResultSet rs, Sql sql) throws SQLException {
                int count = -1;
                if(rs.next()){
                    count = rs.getInt(1);
                }
                return count;
            }
        });
        Entity<T> entity = dao.getEntity(this.persistentClass);
        sql.setEntity(entity);
        dao.execute(sql);
        return sql.getInt();
    }

    /**
     * 按条件分页查询
     * @param sqlName sql名称
     * @param condition 条件
     * @return
     * @author:zhangmengliang
     * @date: 2015年10月14日
     */
    public List<T> search(String sqlName, Condition condition){
        Sql sql = dao.sqls().create(sqlName);
        sql.setCondition(condition);
        return this.search(sql);
    }

    /**
     * 按条件分页查询
     * @param sqlName sql名称
     * @param condition 条件
     * @param currentPage 当前页
     * @param pageSize 每页数量
     * @return
     * @author:zhangmengliang
     * @date: 2015年10月14日
     */
    public List<T> searchByPage(String sqlName, Condition condition, int currentPage, int pageSize){
        Sql sql = dao.sqls().create(sqlName);
        sql.setCondition(condition);
        return this.searchByPage(sql, currentPage, pageSize);
    }

    /**
     * 按条件分页查询
     * @param sql sql对象
     * @return
     * @author:zhangmengliang
     * @date: 2015年10月15日
     */
    public List<T> search(Sql sql){
        sql.setCallback(Sqls.callback.entities());
        Entity<T> entity = dao.getEntity(this.persistentClass);
        sql.setEntity(entity);
        dao.execute(sql);
        return sql.getList(this.persistentClass);
    }

    /**
     * 按条件分页查询
     * @param sql sql对象
     * @param currentPage 当前页
     * @param pageSize 每页数量
     * @return
     * @author:zhangmengliang
     * @date: 2015年10月15日
     */
    public List<T> searchByPage(Sql sql, int currentPage, int pageSize){
        Pager pager = dao.createPager(currentPage, pageSize);
        sql.setCallback(Sqls.callback.entities());
        sql.setPager(pager);
        Entity<T> entity = dao.getEntity(this.persistentClass);
        sql.setEntity(entity);
        dao.execute(sql);
        return sql.getList(this.persistentClass);
    }

    /**
     * 获取指定的关联对象
     * @param t 查询的对象
     * @param fieldName 查询对象内需要获取的对象
     * @throws
     * @author:zhangmengliang
     * @date: 2015年8月9日
     */
    public void findLink(T t, String fieldName){
        dao.fetchLinks(t, fieldName);
    }

    /**
     * 按条件获取指定的关联对象
     * @param t 查询的对象
     * @param fieldName 查询对象内需要获取的对象
     * @param condition 条件
     * @author:zhangmengliang
     * @date: 2015年10月14日
     */
    public void findLink(T t, String fieldName, Condition condition){
        dao.fetchLinks(t, fieldName, condition);
    }

    /**
     * 插入一条新数据
     * @param t 新数据
     * @return
     * @throws
     * @author:zhangmengliang
     * @date: 2015年8月9日
     */
    public T insert(T t){
        return dao.insert(t);
    }

    /**
     * 关联数据信息
     * @param t 对象
     * @param fieldName 被关联的属性
     * @author:zhangmengliang
     * @date: 2015年10月16日
     */
    public T insertRelation(T t, String fieldName){
        return dao.insertRelation(t, fieldName);
    }

    /**
     * 更新
     * @param t 跟新的对象
     * @return true:更新成功;false:更新失败
     * @throws
     * @author:zhangmengliang
     * @date: 2015年8月9日
     */
    public boolean update(T t){
        return dao.update(t) == 1;
    }
    /**
     * 更新(忽略Null)
     * @param t
     * @return
     */
    public boolean updateIgnoreNull(T t){
        return dao.updateIgnoreNull(t) == 1;
    }
    /**
     * 更新(带对象)
     * @param t
     * @param fieldName
     * @return
     */
    public T updateWith(T t, String fieldName){
        return dao.updateWith(t, fieldName);
    }

    /**
     * 按主键删除数据(如果主键标识为@Name)
     * @param id
     * @return
     * @throws
     * @author:zhangmengliang
     * @date: 2015年8月9日
     */
    public boolean delete(String id){
        return dao.delete(this.persistentClass, id) > 0;
    }

    /**
     * 按主键删除数据(如果主键标识为@Id)
     * @param id
     * @return
     * @throws
     * @author:zhangmengliang
     * @date: 2015年8月9日
     */
    public boolean delete(Integer id){
        return dao.delete(this.persistentClass, id) > 0;
    }

    /**
     * 将对象删除的同时，也将符合一个正则表达式的所有关联字段关联的对象统统删除
     * @param t 数据对象
     * @param fildName 正则表达式
     * @return
     * @author:zhangmengliang
     * @date: 2015年11月5日
     */
    public int deleteWith(T t, String fildName){
        return dao.deleteWith(t, fildName);
    }

    /**
     * 按条件清除数据
     * @param condition
     * @return
     * @author:zhangmengliang
     * @date: 2015年9月23日
     */
    public int clear(Condition condition){
        return dao.clear(this.persistentClass, condition);
    }

    /**
     * 清除关联关系
     * @param t 对象
     * @param fieldName 关联的属性
     * @return
     * @author:zhangmengliang
     * @date: 2015年10月17日
     */
    public T clearLinks(T t, String fieldName){
        return dao.clearLinks(t, fieldName);
    }
}